home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1994 / MacHack 1994.toast / MacHack™ 1987-1994 / MacHack™ '93 / Hacks '93 / OK, What was that again? / Application / Utilities.p < prev    next >
Text File  |  1992-06-20  |  10KB  |  444 lines

  1. unit Utilities;
  2.  
  3. interface
  4.     uses Types, Memory, QuickDraw, Resources, Windows, Packages, ToolUtils;
  5.  
  6.     procedure GetGlobalRect (window: WindowPtr;
  7.                                     var globalRect: Rect);
  8.     procedure ForceOnScreen (aWindow: WindowPtr);
  9.     procedure SetToZoomToBestMonitor (window: WindowPtr);
  10.     function WindowZoomed (window: WindowPtr): boolean;
  11.  
  12. {    function CurrentMonitor (window: WindowPtr): gdHandle;}
  13.  
  14.     function Sign (aNumber: integer): integer;
  15.     function Min (a, b: integer): integer;
  16.     procedure ReasonableString (number: longint;
  17.                                     var resultString: str255);
  18.  
  19.     procedure GenericForeColor (color: RGBColor);
  20.     procedure TextBlack;
  21.     procedure TextGray;
  22.     procedure TextLightGray;
  23.  
  24.     procedure PenLightestGray;
  25.     procedure PenLightGray;
  26.     procedure PenGray;
  27.     procedure PenBlack;
  28.  
  29.     function OneBitDeep: boolean;
  30.     function HasColorQuickDraw: boolean;
  31.     function HasSystemSevenOrBetter: boolean;
  32.  
  33.     procedure RememberWindows (theWindow, graphWindow: WindowPtr);
  34.  
  35. implementation
  36.  
  37.     var
  38.         bestDevice: GDHandle;
  39.         bestArea: longint;
  40.         globalWindowRect: Rect;
  41.  
  42.     procedure GetGlobalRect (window: WindowPtr;
  43.                                     var globalRect: Rect);
  44.         var
  45.             savePort: GrafPtr;
  46.     begin    {Return the portRect of window in global coordinates.}
  47.         GetPort(savePort);
  48.         SetPort(window);                    {so that the correct }
  49.         globalRect := window^.portRect;        { coordinate system is used}
  50.         with globalRect do
  51.             begin
  52.                 LocalToGlobal(topLeft);
  53.                 LocalToGlobal(botRight);
  54.             end;
  55.         SetPort(savePort);
  56.     end; {GetGlobalRect}
  57.  
  58.     procedure IsThisTheBestDevice (targetDevice: GDHandle);
  59.         var
  60.             deviceRect: Rect;
  61.             area: longint;
  62.     begin
  63.         deviceRect := targetDevice^^.gdRect;
  64.         if SectRect(deviceRect, globalWindowRect, deviceRect) then
  65.             with deviceRect do
  66.                 begin
  67.                     area := longint(right - left) * longint(bottom - top);
  68.                     if area > bestArea then
  69.                         begin
  70.                             bestArea := area;
  71.                             bestDevice := targetDevice;
  72.                         end;
  73.                 end;
  74.     end;{IsThisTheBestDevice}
  75.  
  76.     procedure ForEachGraphicsDeviceDo (procedure proc (theDevice: GDHandle));
  77.         var
  78.             theGDevice: GDHandle;
  79.     begin
  80.         theGDevice := GetDeviceList;
  81.         while theGDevice <> nil do
  82.             begin
  83. {    if theGDevice^^.devType = screenDevice then }
  84.                 proc(theGDevice);
  85.                 theGDevice := GetNextDevice(theGDevice);
  86.             end;
  87.     end;
  88.  
  89.     function TitleBarHeight (window: WindowPtr): integer;
  90.     begin
  91.         with windowPeek(window)^ do
  92.             TitleBarHeight := contRgn^^.rgnBBox.top - strucRgn^^.rgnBBox.top;
  93.     end;
  94.  
  95.     procedure ZoomRectForThisMonitorAndWindow (gdH: gdHandle;
  96.                                     window: WindowPtr;
  97.                                     var theRect: Rect);
  98.     begin
  99.         theRect := gdH^^.gdRect;
  100.         if gdH = GetMainDevice then
  101.             theRect.top := theRect.top + GetMBarHeight + TitleBarHeight(window)
  102.         else
  103.             theRect.top := theRect.top + TitleBarHeight(window);
  104.     end;
  105.  
  106.     procedure SetToZoomToBestMonitor (window: WindowPtr);
  107.         type
  108.             WSDPtr = ^WStateData;
  109.             WSDH = ^WSDPtr;
  110.         var
  111.             bestRect: Rect;
  112.             stateHandle: Handle;
  113.     begin{SetToZoomToBestMonitor}
  114.         GetGlobalRect(window, globalWindowRect);
  115.         bestDevice := GetMainDevice;
  116.         bestArea := 0;
  117.         ForEachGraphicsDeviceDo(IsThisTheBestDevice);
  118.         ZoomRectForThisMonitorAndWindow(bestDevice, window, bestRect);
  119.         InsetRect(bestRect, 3, 3);
  120.         stateHandle := WindowPeek(window)^.dataHandle;
  121.         WSDH(stateHandle)^^.stdState := bestRect;
  122.     end; {SetToZoomToBestMonitor}
  123.  
  124.     function WindowZoomed (window: WindowPtr): boolean;
  125.         type
  126.             WSDPtr = ^WStateData;
  127.             WSDH = ^WSDPtr;
  128.         var
  129.             bestRect, currentRect: Rect;
  130.             stateHandle: Handle;
  131.     begin{SetToZoomToBestMonitor}
  132.         GetGlobalRect(window, globalWindowRect);
  133.         bestDevice := GetMainDevice;
  134.         bestArea := 0;
  135.         ForEachGraphicsDeviceDo(IsThisTheBestDevice);
  136.         ZoomRectForThisMonitorAndWindow(bestDevice, window, bestRect);
  137.         InsetRect(bestRect, 3, 3);
  138.         stateHandle := WindowPeek(window)^.dataHandle;
  139.         currentRect := WSDH(stateHandle)^^.stdState;
  140.         currentRect := window^.portRect;
  141.         LocalToGlobal(currentRect.topLeft);
  142.         LocalToGlobal(currentRect.botRight);
  143.         WindowZoomed := EqualRect(currentRect, bestRect);
  144.     end;
  145.  
  146.     procedure ForceOnScreen (aWindow: WindowPtr);
  147.         const
  148.             grayRgnLoc = $9EE;
  149.         type
  150.             grayPtrType = ^RgnHandle;
  151.             grayHandleType = ^grayPtrType;
  152.         var
  153.             windowRect: rect;
  154.             grayRgnHandle: RgnHandle;
  155.             grayHandle: grayPtrType;
  156.             wMgr: WindowPtr;
  157.     begin
  158.         windowRect := aWindow^.portRect;
  159.         SetPort(aWindow);
  160.         LocalToGlobal(windowRect.topLeft);
  161.         LocalToGlobal(windowRect.botRight);
  162.         grayHandle := pointer(grayRgnLoc);
  163.         grayRgnHandle := grayHandle^;
  164.  
  165.         if not RectInRgn(windowRect, grayRgnHandle) then
  166.             begin
  167.                 GetWMgrPort(wMgr);
  168.                 SetPort(wMgr);
  169.                 InvertRect(windowRect);
  170.                 MoveWindow(aWindow, 10, 60, TRUE);
  171.                 SetPort(aWindow);
  172.             end;
  173.     end;
  174.  
  175.  
  176.     function Sign (aNumber: integer): integer;
  177.     begin
  178.         if aNumber = 0 then
  179.             Sign := 0
  180.         else if aNumber < 0 then
  181.             Sign := -1
  182.         else
  183.             Sign := 1;
  184.     end;
  185.  
  186.     function Min (a, b: integer): integer;
  187.     begin
  188.         if a < b then
  189.             Min := a
  190.         else
  191.             Min := b;
  192.     end;
  193.  
  194.     procedure ReasonableString (number: longint;
  195.                                     var resultString: str255);
  196.         var
  197.             numer, denom: longint;
  198.             denomStr: str255;
  199.     begin
  200.         if number > 1000000 then
  201.             begin
  202.                 numer := number div 1000000;
  203.                 denom := number - numer * 1000000;
  204.                 NumToString(denom div 100000, denomStr);
  205.                 NumToString(numer, resultString);
  206.                 if denom div 100000 = 0 then
  207.                     resultString := concat(resultString, 'M')
  208.                 else
  209.                     resultString := concat(resultString, '.', denomStr, 'M');
  210.             end
  211.         else if number > 10000 then
  212.             begin
  213.                 numer := number div 1000;
  214.                 denom := number - numer * 1000;
  215.                 NumToString(denom div 100, denomStr);
  216.                 NumToString(numer, resultString);
  217.                 if denom div 100 = 0 then
  218.                     resultString := concat(resultString, 'K')
  219.                 else
  220.                     resultString := concat(resultString, '.', denomStr, 'K');
  221.             end
  222.         else
  223.             begin
  224.                 NumToString(number, resultString);
  225.             end;
  226.     end;
  227.  
  228.     procedure GenericForeColor (color: RGBColor);
  229.     begin
  230. {If we’ve got CQD, then let it map a light color to white}
  231.         if HasColorQuickDraw and not OneBitDeep then
  232.             RGBForeColor(color)
  233.         else if bitor(bitand(longint(color.red), maxint), maxint + 1) > 32767 then
  234.             ForeColor(whiteColor)
  235.         else
  236.             ForeColor(blackColor);
  237.     end;
  238.  
  239.     procedure TextLightGray;
  240.         var
  241.             color: RGBColor;
  242.     begin
  243.         with color do
  244.             begin
  245.                 red := 50000;
  246.                 green := 50000;
  247.                 blue := 50000;
  248.             end;
  249.         GenericForeColor(color);
  250.     end;
  251.  
  252.     procedure TextGray;
  253.         var
  254.             color: RGBColor;
  255.     begin
  256.         with color do
  257.             begin
  258.                 red := 32000;
  259.                 green := 32000;
  260.                 blue := 32000;
  261.             end;
  262.         GenericForeColor(color);
  263.     end;
  264.  
  265.     procedure TextBlack;
  266.     begin
  267.         ForeColor(blackColor);
  268.     end;
  269.  
  270.     procedure PenLightestGray;
  271.         var
  272.             color: RGBColor;
  273.     begin
  274.         with color do
  275.             begin
  276.                 red := $FFF0;
  277.                 green := $FFF0;
  278.                 blue := $FFF0;
  279.             end;
  280.         if OneBitDeep then
  281.             begin
  282.                 PenNormal;
  283.                 ForeColor(whiteColor);
  284.                 BackColor(whiteColor);
  285.             end
  286.         else
  287.             GenericForeColor(color);
  288.     end;
  289.  
  290.     procedure PenLightGray;
  291.         var
  292.             color: RGBColor;
  293.     begin
  294.         with color do
  295.             begin
  296.                 red := 50000;
  297.                 green := 50000;
  298.                 blue := 50000;
  299.             end;
  300.         if OneBitDeep then
  301.             begin
  302.                 PenNormal;
  303.                 ForeColor(whiteColor);
  304.             end
  305.         else
  306.             RGBForeColor(color);
  307.     end;
  308.  
  309.     procedure PenGray;
  310.         var
  311.             color: RGBColor;
  312.     begin
  313.         with color do
  314.             begin
  315.                 red := 32000;
  316.                 green := 32000;
  317.                 blue := 32000;
  318.             end;
  319.         if OneBitDeep then
  320.             begin
  321.                 PenNormal;
  322.                 PenPat(gray);
  323.             end
  324.         else
  325.             RGBForeColor(color);
  326.         TextMode(srcOr);
  327.     end;
  328.  
  329.     procedure PenBlack;
  330.     begin
  331.         ForeColor(blackColor);
  332.         TextMode(srcOr);
  333.         PenPat(black);
  334.     end;
  335.  
  336.     function OneBitDeep: boolean;
  337.         var
  338.             theRect: rect;
  339.             deviceHandle: gdHandle;
  340.     begin
  341.         OneBitDeep := true;
  342.         if not HasColorQuickDraw then
  343.             exit(OneBitDeep);
  344.         theRect := thePort^.portRect;
  345.         deviceHandle := GetMaxDevice(theRect);
  346.         if deviceHandle <> nil then
  347.             OneBitDeep := deviceHandle^^.gdPMap^^.pixelSize <= 2;
  348.     end;
  349.  
  350.     function SimpleGestalt (selector: OSType;
  351.                                     var response: LongInt): OSErr;
  352.     external;
  353.  
  354.     const
  355.         gestaltQuickDrawVersion = 'qd  ';
  356.         gestalt8BitQD = $100;
  357.     function HasColorQuickDraw: boolean;
  358.         var
  359.             err: integer;
  360.             result: longint;
  361.     begin
  362.         err := SimpleGestalt(gestaltQuickDrawVersion, result);
  363.         HasColorQuickDraw := (result >= gestalt8BitQD);
  364.     end;
  365.  
  366.     const
  367.         gestaltSystemVersion = 'sysv';
  368.     function HasSystemSevenOrBetter: boolean;
  369.         var
  370.             err: integer;
  371.             result: longint;
  372.     begin
  373.         err := SimpleGestalt(gestaltSystemVersion, result);
  374.         HasSystemSevenOrBetter := (LoWord(result) >= $700);
  375.     end;
  376.  
  377.  
  378. {Take aWindow and modify it's corresponding WIND resource so we can open it in the same size and position on next launch}
  379.     procedure RememberWindow (aWindow: WindowPtr;
  380.                                     resID: integer);
  381.         type
  382.             windType = record
  383.                     boundsRect: rect;
  384.                     procId: integer;
  385.                     visible: byte;
  386.                     filler1: byte;
  387.                     goAway: byte;
  388.                     filler2: byte;
  389.                     refCon: longint;
  390.                     title: str255;
  391.                 end;
  392.             windTypePtr = ^windType;
  393.             windTypeHandle = ^windTypePtr;
  394.         var
  395.             myWind: windTypeHandle;
  396.     begin
  397.         SetPort(aWindow);
  398.         myWind := windTypeHandle(Get1Resource('WIND', resID));
  399.         if myWind <> nil then
  400.             begin
  401.                 myWind^^.boundsRect := aWindow^.portRect;
  402.                 LocalToGlobal(myWind^^.boundsRect.topLeft);
  403.                 LocalToGlobal(myWind^^.boundsRect.botRight);
  404.                 if WindowPeek(aWindow)^.visible then
  405.                     INTEGER(myWind^^.visible) := $0101
  406.                 else
  407.                     INTEGER(myWind^^.visible) := $0001;
  408.                 ChangedResource(Handle(myWind));
  409.                 WriteResource(Handle(myWind));
  410.                 ReleaseResource(Handle(myWind));
  411.             end;
  412.     end;
  413.  
  414.     procedure RememberWindows (theWindow, graphWindow: WindowPtr);
  415.     begin
  416.         RememberWindow(theWindow, 128);
  417.         RememberWindow(graphWindow, 129);
  418.     end;
  419.  
  420.     procedure DrawGrayRamp;
  421.         var
  422.             i: integer;
  423.             color: RGBColor;
  424.     begin
  425.         SetPort(FrontWindow);
  426.         for i := 1 to 256 do
  427.             begin
  428.                 with color do
  429.                     begin
  430.                         red := i * 256;
  431.                         blue := red;
  432.                         green := red;
  433.                     end;
  434.                 PenSize(2, 2);
  435.                 RGBForeColor(color);
  436.                 MoveTo(i * 2, 0);
  437.                 LineTo(i * 2, thePort^.portRect.bottom);
  438.             end;
  439.         repeat
  440.         until button;
  441.     end;
  442.  
  443.  
  444. end.